package cn.itcast.order.sentinel;

import com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.BlockExceptionHandler;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.csp.sentinel.slots.block.authority.AuthorityException;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeException;
import com.alibaba.csp.sentinel.slots.block.flow.FlowException;
import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowException;
import com.alibaba.csp.sentinel.slots.system.SystemBlockException;
import org.apache.http.entity.ContentType;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 自定义sentinel异常结果, 需要实现BlockExceptionHandler
 *
 * @author llhuang10
 * @date 2021/9/15 22:32
 */
@Component
public class SentinelBlockHandler implements BlockExceptionHandler {


    @Override
    public void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, BlockException e) throws Exception {
        String msg = "未知异常";
        int status = 429;
        if (e instanceof FlowException) {
            msg = "请求被限流了";
        } else if (e instanceof DegradeException) {
            msg = "请求被熔断降级了";
        } else if (e instanceof ParamFlowException) {
            // todo 这里直接抛出500的异常了
            // 09-15 22:53:09:420 ERROR 7116 --- [io-8081-exec-10] o.a.c.c.C.[.[.[/].[dispatcherServlet]    :
            // Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.reflect.UndeclaredThrowableException] with root cause
            msg = "热点参数限流";
        } else if (e instanceof AuthorityException) {
            msg = "请求没有权限";
            status = 401;
        } else if (e instanceof SystemBlockException) {
            msg = "请求不符合系统保护规则!";
        }

        // httpServletResponse.setContentType("application/json;charset=utf-8");
        httpServletResponse.setContentType(ContentType.APPLICATION_JSON.toString());
        httpServletResponse.setStatus(status);
        httpServletResponse.getWriter().println("{\"message\": \"" + msg + "\", \"status\": " + status + "}");
    }
}
